package com.suke.czx.modules.wx.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.service.WxPayService;
import com.suke.czx.common.utils.DateUtils;
import com.suke.czx.common.utils.JsonResult;
import com.suke.czx.common.utils.UUIDS;
import com.suke.czx.modules.wx.util.CodeUtil;
import com.suke.czx.modules.wxadmin.entity.DkCourseEntity;
import com.suke.czx.modules.wxadmin.entity.DkDisEntity;
import com.suke.czx.modules.wxadmin.entity.DkReadPlanEntity;
import com.suke.czx.modules.wxadmin.entity.DkResourceEntity;
import com.suke.czx.modules.wxadmin.entity.DkUserEntity;
import com.suke.czx.modules.wxadmin.entity.DkUserOrderEntity;
import com.suke.czx.modules.wxadmin.service.DkCourseService;
import com.suke.czx.modules.wxadmin.service.DkDisService;
import com.suke.czx.modules.wxadmin.service.DkReadPlanService;
import com.suke.czx.modules.wxadmin.service.DkResourceService;
import com.suke.czx.modules.wxadmin.service.DkUserOrderService;
import com.suke.czx.modules.wxadmin.service.DkUserService;

/**
 * @author Binary Wang
 */
@RestController
@RequestMapping("/wx/pay")
public class WxPayController extends BaseController {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private WxPayService wxPayService;
	@Autowired
	private DkCourseService dkCourseService;
	@Autowired
	private DkUserOrderService dkUserOrderService;
	@Autowired
	private DkResourceService dkResourceService;
	@Autowired
	private DkReadPlanService dkReadPlanService;
	@Autowired
	private DkUserService dkUserService;
	@Autowired
	private DkDisService dkDisService;
	
	

	@RequestMapping("/createOrder")
	public String createOrder(String openid, @RequestParam(defaultValue="1")Integer courseId,String dis) {
		// 查询配置活动信息，构建订单价格；
		DkCourseEntity course = dkCourseService.queryObject(courseId);
		DkDisEntity dkdis = null;
		if(null!=dis&&!dis.equals("")){
			dkdis =dkDisService.queryObject(dis);
			if(null!=dkdis){
				course.setPriceOff(dkdis.getDisPrice());
			}
		}
		
		// 构建未处理订单，并且保存未处理订单
		DkUserOrderEntity order = new DkUserOrderEntity();
		order.setCourseId(course.getId());
		order.setOrderNo(CodeUtil.createOrderNo());
		order.setStatus(0);
		order.setTotalFee(course.getPriceOff());
		order.setUserId(openid);
		order.setUpdateTime(new Date());
		order.setPayReason(1);
		if(null==dkdis){
			order.setDisId("0");
		}else{
			order.setDisId(dkdis.getId());
		}
		dkUserOrderService.save(order);

		try {
			WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
			orderRequest.setBody(course.getCourseName());
			orderRequest.setOutTradeNo(order.getOrderNo());
			orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(order.getTotalFee().toPlainString()));// 元转成分
			orderRequest.setOpenid(openid);
			orderRequest.setSpbillCreateIp(CodeUtil.getIpAddr(getRequest()));
			orderRequest.setNotifyUrl("http://dk2019.hbanbao.com/x_springboot/wx/pay/notify/buy");
			orderRequest.setTradeType("JSAPI");
			return new JsonResult(200, "ok", wxPayService.createOrder(orderRequest)).toJson();
		} catch (Exception e) {
			logger.error("微信支付失败！订单号：{},原因:{}", order.getOrderNo(), e.getMessage());
			e.printStackTrace();
			return new JsonResult(-1, "微信支付异常").toJson();
		}

	}
	@RequestMapping("/createOrderRepair")
	public String createOrderRepair(String openid, @RequestParam(defaultValue="1")Integer courseId,String dateStr) {
		
		//检查对应日期是否打卡，避免重复支付打卡费用
		Map<String,String> parms = new HashMap<String,String>();
		parms.put("readDate", dateStr);
		parms.put("userId", openid);
		DkReadPlanEntity plan = dkReadPlanService.queryUserReadPlanByIdAndDate(parms);
		if(null==plan||plan.getStatus()==1){
			return new JsonResult(-1, "不需要补卡").toJson();
		}
		
		// 查询配置活动信息，构建订单价格；
		DkCourseEntity course = dkCourseService.queryObject(courseId);
		
		// 构建未处理订单，并且保存未处理订单
		DkUserOrderEntity order = new DkUserOrderEntity();
		order.setCourseId(course.getId());
		order.setOrderNo(CodeUtil.createOrderNo());
		order.setStatus(0);
		
		if(plan.getResourceId()>=11){
			order.setTotalFee(course.getReplenPrice().multiply(new BigDecimal(2)));
		}else{
			order.setTotalFee(course.getReplenPrice());
		}
		
		order.setUserId(openid);
		order.setUpdateTime(new Date());
		order.setPayReason(2);
		dkUserOrderService.save(order);

		try {
			WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
			orderRequest.setBody(dateStr);
			orderRequest.setOutTradeNo(order.getOrderNo());
			orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(order.getTotalFee().toPlainString()));// 元转成分
			orderRequest.setOpenid(openid);
			orderRequest.setSpbillCreateIp(CodeUtil.getIpAddr(getRequest()));
			orderRequest.setNotifyUrl("http://dk2019.hbanbao.com/x_springboot/wx/pay/notify/Repair");
			orderRequest.setTradeType("JSAPI");
			orderRequest.setAttach(dateStr);
			return new JsonResult(200, "ok", wxPayService.createOrder(orderRequest)).toJson();
		} catch (Exception e) {
			logger.error("微信支付失败！订单号：{},原因:{}", order.getOrderNo(), e.getMessage());
			e.printStackTrace();
			return new JsonResult(-1, "微信支付异常").toJson();
		}

	}
	
	@RequestMapping("/notify/Repair")
	@ResponseBody
	public String payNotifyRepair(HttpServletRequest request, HttpServletResponse response) {
		try {
			String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
			WxPayOrderNotifyResult result = wxPayService.parseOrderNotifyResult(xmlResult);
			// 结果正确
			String orderId = result.getOutTradeNo();
			String tradeNo = result.getTransactionId();
			String totalFee = BaseWxPayResult.fenToYuan(result.getTotalFee());
			String dateStr = result.getAttach();
			Date date = new Date();
			// 自己处理订单的业务逻辑，需要判断订单是否已经支付过，否则可能会重复调用
			//更新订单相关信息
			DkUserOrderEntity order = dkUserOrderService.queryObject(orderId);
			DkCourseEntity course = dkCourseService.queryObject(order.getCourseId());
			order.setStatus(1);
			order.setPayResult(tradeNo);
			order.setStartTime(DateUtils.format(new Date(), DateUtils.DATE_PATTERN));
			order.setEndTime(DateUtils.getDate(date,course.getPlanDays()));
			dkUserOrderService.update(order);
			
			Map<String,String> parms = new HashMap<String,String>();
			parms.put("readDate", dateStr);
			parms.put("userId", order.getUserId());
			
			DkReadPlanEntity plan = dkReadPlanService.queryUserReadPlanByIdAndDate(parms);
			plan.setStatus(1);
			plan.setReadtime(new Date());
			dkReadPlanService.update(plan);
			
			return WxPayNotifyResponse.success("处理成功!");
		} catch (Exception e) {
			logger.error("微信回调结果异常,异常原因{}", e.getMessage());
			return WxPayNotifyResponse.fail(e.getMessage());
		}
	}

	@RequestMapping("/notify/buy")
	@ResponseBody
	public String payNotify(HttpServletRequest request, HttpServletResponse response) {
		try {
			String xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
			WxPayOrderNotifyResult result = wxPayService.parseOrderNotifyResult(xmlResult);
			// 结果正确
			String orderId = result.getOutTradeNo();
			String tradeNo = result.getTransactionId();
//			String totalFee = BaseWxPayResult.fenToYuan(result.getTotalFee());
			Date date = new Date();
			// 自己处理订单的业务逻辑，需要判断订单是否已经支付过，否则可能会重复调用
			//更新订单相关信息
			DkUserOrderEntity order = dkUserOrderService.queryObject(orderId);
			if(order.getStatus()!=1){
				DkCourseEntity course = dkCourseService.queryObject(order.getCourseId());
				order.setStatus(1);
				order.setPayResult(tradeNo);
				order.setStartTime(DateUtils.format(new Date(), DateUtils.DATE_PATTERN));
				order.setEndTime(DateUtils.getDate(date,course.getPlanDays()));
				dkUserOrderService.update(order);
			}else{
				return WxPayNotifyResponse.success("处理成功!");
			}
			
			//1、获取构建计划相关数据，根据活动ID
			List<DkResourceEntity> dkrs = dkResourceService.querySysResourceByCourseId(order.getCourseId());
			//更新用户信息
			
			DkUserEntity dkUser = dkUserService.queryObject(order.getUserId());
			if(dkUser.getState()!=1){
				dkUser.setOrdertime(date);
				dkUser.setState(1);
				dkUser.setStartTime(DateUtils.getDate(date, 0));
				dkUser.setEndTime(DateUtils.getDate(date, dkrs.size()-1));
				dkUserService.update(dkUser);
			}else{
				return WxPayNotifyResponse.success("处理成功!");
			}
			//构建用户打卡计划前，判断用户是否已经有学习计划了，如果已经有了，就不再构建直接返回
			
			List<DkReadPlanEntity> plans = dkReadPlanService.queryUserReadPlanById(dkUser.getOpenid());
			if(null==plans||plans.size()==0){
				//2、构建学习计划
				plans = new ArrayList<DkReadPlanEntity>();
				for(int i=0 ; i<dkrs.size() ; i++){
					DkReadPlanEntity plan = new DkReadPlanEntity();
					plan.setId(UUIDS.getUUID());
					plan.setCreatetime(new Date());
					plan.setReadDate(DateUtils.getDate(date,i));
					plan.setResourceId(dkrs.get(i).getId());
					Calendar cal = Calendar.getInstance();
					int h = cal.get(Calendar.HOUR_OF_DAY);
					plan.setStatus(0);
					if(h==22||h==23){
						if(i==0){
							plan.setStatus(1);
						}
					}
					plan.setUserId(order.getUserId());
					plan.setSendState(0);
					plans.add(plan);
				}
				dkReadPlanService.batchInsertUserReadPlan(plans);
			}
			
			return WxPayNotifyResponse.success("处理成功!");
		} catch (Exception e) {
			logger.error("微信回调结果异常,异常原因{}", e.getMessage());
			return WxPayNotifyResponse.fail(e.getMessage());
		}
	}

}